/*
 * Copyright 2014, General Dynamics C4 Systems
 *
 * SPDX-License-Identifier: GPL-2.0-only
 */

#pragma once

#define CR0_MONITOR_COPROC  BIT(1)  /* Trap on FPU "WAIT" commands. *//*Z 使能监控协处理器任务切换 */
#define CR0_EMULATION       BIT(2)  /* Enable OS emulation of FPU. *//*Z 无x87协处理器 */
#define CR0_TASK_SWITCH     BIT(3)  /* Trap on any FPU usage, for lazy FPU. *//*Z 允许FPU上下文延迟保存 */
#define CR0_NUMERIC_ERROR   BIT(5)  /* Internally handle FPU problems. *//*Z 使能FPU错误内部报告机制 */
#define CR0_WRITE_PROTECT   BIT(16) /* Write protection in supervisor mode. *//*Z 特权例程也不能写只读页，如应用COW机制时 */
#define CR4_PCE             BIT(8)  /* Performance-Monitoring Counter enable. *//*Z 性能监测计数器读指令的执行权限：0-特权，1-任意 */
#define CR4_OSFXSR          BIT(9)  /* Enable SSE et. al. features. *//*Z 使能SSE系列指令 */
#define CR4_OSXMMEXCPT      BIT(10) /* Enable SSE exceptions. */
#define CR4_OSXSAVE         BIT(18) /* Enavle XSAVE feature set *//*Z 使能XSAVE系列指令 */
#define CR4_VMXE            BIT(13) /* Enable VMX mode. *//*Z 使能VMX（虚拟机技术）*/
#define CR4_SMEP            BIT(20) /* Supervisor Mode Execution Prevention. *//*Z 阻止特权代码执行（读取）用户空间的指令 */
#define CR4_SMAP            BIT(21) /* Supervisor Mode Access Prevention. *//*Z 可能阻止特权代码访问用户空间的数据 */

#define FLAGS_TF            BIT(8)  /* Trap Flag *//*Z 使能单步例外 */
#define FLAGS_IF            BIT(9)  /* Interrupt enable Flag *//*Z 使能中断 */
#define FLAGS_HIGH          BIT(1)  /* Bits in the FLAGS register that must be high *//*Z Intel要求恒为1 */
#define FLAGS_LOW           (BIT(3) | BIT(5)) /* Bits in the FLAGS register that must be low *//*Z Intel要求恒为0 */
#define FLAGS_MASK          MASK(12)/* Only the first 12 bits of the FLAGS are used, rest should be zero *//*Z seL4只关心低12位 */
#define FLAGS_USER_DEFAULT  FLAGS_IF | FLAGS_HIGH   /*Z 默认使能中断 */
/*Z 借用内存访问引入编译器屏障 */
/* We use a dummy variable to synchronize reads and writes to the control registers.
 * this allows us to write inline asm blocks that do not have enforced memory
 * clobbers for ordering. */
static unsigned long control_reg_order;

#include <mode/machine/cpu_registers.h>
/*Z 将value值写入reg指示的XCR(extended control register)寄存器 */
static inline void xsetbv(uint32_t reg, uint64_t value)
{
    asm volatile("xsetbv" :: "d"((uint32_t)(value >> 32)), "a"((uint32_t)(value & 0xffffffff)), "c"(reg), "m"(control_reg_order));
}
/*Z 将value写入XCR0寄存器 */
static inline void write_xcr0(uint64_t value)
{
    xsetbv(0, value);
}

